'use strict';

// 导入uni-id-common模块和加密模块
const uniID = require('uni-id-common');
const db = uniCloud.database();
const crypto = require('crypto');

/**
 * 手机号登录云函数
 * @param {Object} event 客户端传入的参数
 * @param {String} event.code 微信登录获取的code
 * @param {String} event.encryptedData 加密的用户数据
 * @param {String} event.iv 加密算法的初始向量
 * @param {Object} context 上下文信息
 */
exports.main = async (event, context) => {
  const { code, encryptedData, iv } = event;
  
  // 初始化uniID实例，显式传入配置
  const uniIDIns = uniID.createInstance({
    context,
    config: {
      tokenSecret: "your-token-secret",
      tokenExpiresIn: 7200
    }
  });
  
  // 微信小程序配置
  const appid = 'wx59ebd5ee8adaaa55';
  const appsecret = '4d68f17bea02434abb7def50e034d8ee';
  
  // 校验参数
  if (!code || !encryptedData || !iv) {
    return {
      code: 1,
      message: '缺少必要参数'
    };
  }
  
  if (!appid || !appsecret) {
    return {
      code: 1,
      message: '微信配置不完整，请检查appid和appsecret'
    };
  }
  
  try {
    // 第一步：调用微信登录接口获取session_key
    const loginRes = await uniCloud.httpclient.request(
      `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${appsecret}&js_code=${code}&grant_type=authorization_code`,
      {
        method: 'GET',
        dataType: 'json'
      }
    );
    
    // 检查请求是否成功
    if (loginRes.status !== 200) {
      return {
        code: 1,
        message: '微信服务器请求失败',
        data: loginRes
      };
    }
    
    const { openid, session_key, unionid } = loginRes.data;
    
    // 检查是否获取到openid和session_key
    if (!openid || !session_key) {
      return {
        code: 1,
        message: '获取openid或session_key失败',
        data: loginRes.data
      };
    }
    
    // 第二步：解密手机号
    let phoneInfo = null;
    try {
      phoneInfo = decryptData(encryptedData, session_key, iv, appid);
    } catch (error) {
      console.error('解密手机号失败:', error);
      return {
        code: 1,
        message: '解密手机号失败',
        data: error.message
      };
    }
    
    // 检查是否解密出手机号
    if (!phoneInfo.phoneNumber) {
      return {
        code: 1,
        message: '获取手机号失败',
        data: phoneInfo
      };
    }
    
    // 第三步：根据openid查询用户是否已存在
    const userCollection = db.collection('uni-id-users');
    const userRes = await userCollection.where({
      wx_openid: openid
    }).get();
    
    let userInfo;
    let userId;
    
    if (userRes.data.length === 0) {
      // 用户不存在，创建新用户
      const userData = {
        wx_openid: openid,
        wx_unionid: unionid,
        phoneNumber: phoneInfo.phoneNumber,
        purePhoneNumber: phoneInfo.purePhoneNumber,
        countryCode: phoneInfo.countryCode,
        register_date: Date.now(),
        register_ip: context.CLIENTIP,
        status: 0, // 正常状态
        avatar: '' // 初始头像为空
      };
      
      const addRes = await userCollection.add(userData);
      userId = addRes.id;
      
      // 查询新创建的用户
      const newUserRes = await userCollection.doc(userId).get();
      userInfo = newUserRes.data;
    } else {
      // 用户已存在，更新手机号信息和最后登录时间
      userId = userRes.data[0]._id;
      userInfo = userRes.data[0];
      
      // 更新用户信息
      await userCollection.doc(userId).update({
        phoneNumber: phoneInfo.phoneNumber,
        purePhoneNumber: phoneInfo.purePhoneNumber,
        countryCode: phoneInfo.countryCode,
        last_login_date: Date.now(),
        last_login_ip: context.CLIENTIP
      });
      
      // 重新查询用户信息
      const updatedUserRes = await userCollection.doc(userId).get();
      userInfo = updatedUserRes.data;
    }
    
    // 第四步：生成token
    const tokenRes = await uniIDIns.createToken({
      uid: userId
    });
    
    // 检查token生成是否成功
    if (tokenRes.code) {
      return {
        code: tokenRes.code,
        message: tokenRes.errMsg || '生成token失败'
      };
    }
    
    return {
      code: 0,
      message: '登录成功',
      token: tokenRes.token,
      tokenExpired: tokenRes.tokenExpired,
      userId: userId,
      userInfo: {
        // 构建一个安全的用户信息对象，确保所有需要的字段都有默认值
        userId: userId,
        phoneNumber: phoneInfo.phoneNumber,
        wx_openid: userInfo.wx_openid,
        // 确保gender字段有默认值
        gender: userInfo.gender || 0,
        birthYear: userInfo.birthYear || '',
        address: userInfo.address || '',
        nickname: userInfo.nickname || '',
        avatar: userInfo.avatar || '',
        register_date: userInfo.register_date,
        last_login_date: userInfo.last_login_date
      },
      phoneNumber: phoneInfo.phoneNumber
    };
  } catch (error) {
    console.error('手机号登录失败:', error);
    return {
      code: 1,
      message: '登录失败',
      data: error.message
    };
  }
};

/**
 * 解密微信加密数据
 * @param {String} encryptedData 加密数据
 * @param {String} sessionKey 会话密钥
 * @param {String} iv 初始向量
 * @param {String} appid 小程序appid
 * @returns {Object} 解密后的数据
 */
function decryptData(encryptedData, sessionKey, iv, appid) {
  // base64 decode
  const sessionKeyBuffer = Buffer.from(sessionKey, 'base64');
  const encryptedDataBuffer = Buffer.from(encryptedData, 'base64');
  const ivBuffer = Buffer.from(iv, 'base64');
  
  try {
    // 解密
    const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKeyBuffer, ivBuffer);
    // 设置自动 padding 为 true，删除填充补位
    decipher.setAutoPadding(true);
    let decoded = decipher.update(encryptedDataBuffer, 'binary', 'utf8');
    decoded += decipher.final('utf8');
    
    decoded = JSON.parse(decoded);
    
    // 验证解密后的数据是否正确
    if (decoded.watermark.appid !== appid) {
      throw new Error('Invalid appid');
    }
    
    return decoded;
  } catch (err) {
    throw new Error('Illegal Buffer');
  }
}